#ifndef COLOR_H
#define COLOR_H

#include <iostream>


class Color {
	
	public: 
		
	typedef float T;
	typedef unsigned int uint;
	
	T r, g, b, a; // rgba or hsva
	
	Color ():
	r(1), g(1), b(1), a(1)
	{}

	Color (T _r, T _g, T _b, T _a):
	r(_r), g(_g), b(_b), a(_a)
	{}

	operator T*(){
		return (T*)this;
	}
		
	void operator +=(Color C){
	
		r+=C.r;	g+=C.g;	b+=C.b; a+=C.a; // substitute with bit shift !!!
	
		if (r<0) r++; else if (1<r) r--;
		if (g<0) g=0; else if (1<g) g = 1;
		if (b<0) b=0; else if (1<b) b = 1;
		if (a<0) a=0; else if (1<a) a = 1;
	
	}	
	
	Color HSV2RGB(T h, T s, T v) {

		float r = R(6*h);
		float g = G(6*h);
		float b = B(6*h);
		
		this->r = v*(r + (1-s)*(1-r));
		this->g = v*(g + (1-s)*(1-g));
		this->b = v*(b + (1-s)*(1-b));
		
		return *this;

	}

	static Color HSVAToRGBA(Color hsva){

		float r = Color::R(6*hsva.r);
		float g = Color::G(6*hsva.r);
		float b = Color::B(6*hsva.r);
	
		return Color(
			hsva.b*(r + (1-hsva.g)*(1-r)),
			hsva.b*(g + (1-hsva.g)*(1-g)),
			hsva.b*(b + (1-hsva.g)*(1-b)),
			hsva.a );

	}


	uint getColor() {
		return 256*256*int(255*r) + 256*int(255*g) + int(255*b);
		//return uint(255*r) + 256*uint(255*g) + 256*256*uint(255*b);
	}

	private:
		
		static float R(float h) {
	
			if (1 <= h && h < 2) return 2-h;
			if (2 <= h && h < 4) return 0;
			if (4 <= h && h < 5) return h-4;
	
			return 1;
		}

		static float G(float h){
	
			if (          h < 1) return h;
			if (1 <= h && h < 3) return 1;
			if (3 <= h && h < 4) return 4-h;
	
			return 0;
		}

		static float B(float h){
	
			if (          h < 2) return 0;
			if (2 <= h && h < 3) return h-2;
			if (5 <= h && h < 6) return 6-h;
	
			return 1;
		}

};

#endif
